#ifndef	_ARH_KONTEKST_H_
#define	_ARH_KONTEKST_H_

#include "tipovi.h"
#include "spremnik.h"

//pocetne zastavice za korisnicku dretvu: IF postavljen, razina 3
#define	POC_REG_STANJA		0x3202

//pocetne zastavice za jezgrinu dretvu: IF postavljen, razina 0
#define	POC_REG_STANJA_JD	0x0202

//makroi za rad sa stogom
#define POCETAK_STOGA(stog, vel)	((void *) (((void *) stog) + (vel)))
//'stog' mora biti varijabla!
#define STAVI_NA_STOG(stog, pod)	{	uint32 *ps = stog;	 \
						*(--ps) = (uint32) (pod);\
						stog = ps;		 \
					}

//konteks dretve - ono sto se na stogu nalazi po prekidu
//za korisnicku dretvu ovo je u opisniku dretve
//za jezgrinu dretvu to je na njenom stogu
typedef struct _kontekst_dretve_t_ {
	uint16 gs, fs, es, ds;
	uint32 registri[8];
	uint32 kod_greske;
	uint32 eip;
	uint32 cs;
	uint32 eflags;
	uint32 esp;	// *
	uint32 ss;	// *
} __attribute__((__packed__)) kontekst_dretve_t;
// "*" - samo za korisnicke dretve, pri prekidu jezgrine dretve ovi se elementi
// ne koriste

//puni kontekst dretve (dodatno podaci i o koristenom spremnickom prostoru)
typedef struct _arh_kontekst_t_ {
	kontekst_dretve_t kontekst;

	arh_spremnik_t *spremnik;

	//mali kontekst potreban pri prekidima
	uint32 esp;	//stog dretve
	uint32 ss;	//opisnik stoga

} __attribute__((__packed__)) arh_kontekst_t;

//prije povratka u dretvu
void arh_azuriraj_kontekst (void *_kontekst);

//pri prekidu, prije obrade
void arh_pohrani_adresu_konteksta (void *_kontekst, void *vrh_stoga);

//u obradi prekida - na stogu dretve se nalaze parametri za jezgrinu funkciju
void *arh_dohvati_vrh_stoga_dretve ( void *_spremnik, void *_kontekst );

// stog dretve mora biti spreman za povratak iz prekida
void arh_izgradi_pocetni_stog ( void *_spremnik, void *_kontekst,
			         void *stog, void *pokreni_dretvu,
			         void *poc_funkc, void *param);

//umetanje obrade pri pojavi prioritetnijih dogadjaja
void *arh_dodaj_obradu (void *spr, void *_kontekst, void *obrada,
			uint32 vp_na_stogu, ...);

//obnavljanje stoga (prekidnog) pri zavrsetku obrade dogadjaja
void arh_makni_obradu (void *_kontekst, void *vrh_stoga);

//ispis konteksta - za testiranje gornjih funkcija
void arh_ispisi_kontekst (void *_kontekst);

#endif	/* _ARH_KONTEKST_H_ */
